package com.junjie.blibli.service.impl;

import com.junjie.blibli.Constant.UserConstant;
import com.junjie.blibli.Entity.FollowingGroup;
import com.junjie.blibli.Entity.User;
import com.junjie.blibli.Entity.UserFollowing;
import com.junjie.blibli.Entity.UserInfo;
import com.junjie.blibli.Exception.http.ConditionException;
import com.junjie.blibli.dao.UserFollowingDao;
import com.junjie.blibli.service.FollowingGroupService;
import com.junjie.blibli.service.UserFollowingService;
import com.junjie.blibli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserFollowingServiceImpl implements UserFollowingService {
    @Autowired
    private UserFollowingDao userFollowingDao;

    @Autowired
    private FollowingGroupService followingGroupService;

    @Autowired
    private UserService userService;

    //添加关注用户
    @Transactional
    public void addUserFollowings(UserFollowing userFollowing){
        Long groupId = userFollowing.getGroupId();
        //分组ID不存在的情况下，使用默认分组
        if(groupId==null){
            FollowingGroup followingGroup = followingGroupService.getByType(UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT);
            userFollowing.setGroupId(followingGroup.getId());
        }else{
            FollowingGroup followingGroup = followingGroupService.getById(groupId);
            if(followingGroup==null) throw new ConditionException("分组不存在");
        }
        Long followingId = userFollowing.getUserId();
        User user = userService.getUserById(followingId);
        if(user==null) throw new ConditionException("关注用户不存在");

        //删除数据库中之前的该用户与被关注用户的关系
        userFollowingDao.deleteUserFollowing(userFollowing.getUserId(), followingId);
        //添加时间
        userFollowing.setCreateTime(new Date());
        userFollowingDao.addUserFollowing(userFollowing);
    }

    //第一步，获取关注的用户列表
    //第二步，根据关注用户的id查询关注用户的基本信息
    //第三步，将关注用户按关注分组进行分类
    public List<FollowingGroup> getUserFollowings(Long userId){
        List<UserFollowing> list = userFollowingDao.getUserFollowings(userId);
        Set<Long> FollowingIdSet = list.stream().map(UserFollowing::getFollowingId).collect(Collectors.toSet());
        List<UserInfo> userInfoList = new ArrayList<>();
        if(FollowingIdSet.size()>0){
            userInfoList = userService.getUserInfoByIds(FollowingIdSet);
        }
        //用户信息匹配
        for (UserFollowing userFollowing : list) {
            for (UserInfo userInfo : userInfoList) {
                if(userFollowing.getFollowingId().equals(userInfo.getUserId())){
                    userFollowing.setUserInfo(userInfo);
                }
            }
        }
        //根据用户ID，把所有分组查出来
        List<FollowingGroup> groupList = followingGroupService.getByUserId(userId);
        //全部关注分组不用存在数据库中，直接在这里new出来
        FollowingGroup allGroup = new FollowingGroup();
        allGroup.setName(UserConstant.USER_FOLLOWING_GROUP_ALL_NAME);
        allGroup.setFollowingUserInfoList(userInfoList);

        //result集合
        List<FollowingGroup> result = new ArrayList<>();
        result.add(allGroup);

        for (FollowingGroup group : groupList) {
            List<UserInfo> infoList = new ArrayList<>();
            for (UserFollowing userFollowing : list) {
                if(group.getId().equals(userFollowing.getGroupId())){
                    infoList.add(userFollowing.getUserInfo());
                }
            }
            group.setFollowingUserInfoList(infoList);
            result.add(group);
        }
        return result;
    }

    /**
     * 获取用户粉丝列表
     * 根据粉丝用户ID查询基本信息
     * 查询当前用户是否已经关注该粉丝（互粉）
     */
    public List<UserFollowing> getUserFans(Long userId){
        List<UserFollowing> fanList = userFollowingDao.getUserFans(userId);
        Set<Long> FanIdSet = fanList.stream().map(UserFollowing::getFollowingId).collect(Collectors.toSet());
        List<UserInfo> userInfoList = new ArrayList<>();
        if(FanIdSet.size()>0){
            userInfoList = userService.getUserInfoByIds(FanIdSet);
        }
        //查询当前用户所有关注
        List<UserFollowing> followingList = userFollowingDao.getUserFollowings(userId);
        for (UserFollowing fan : fanList) {
            for (UserInfo userInfo : userInfoList) {
                if(fan.getUserId().equals(userInfo.getUserId())){
                    //初始化是否互关，默认不是互关的，为false
                    userInfo.setFollowed(false);
                    fan.setUserInfo(userInfo);
                }
            }
            //检查是否是互粉状态
            for (UserFollowing following : followingList) {
                if(following.getFollowingId().equals(fan.getUserId())){
                    fan.getUserInfo().setFollowed(true);
                }
            }
        }

        return fanList;
    }

    //用户添加分组
    @Override
    public Long addUserFollowingsGroups(FollowingGroup followingGroup) {
        followingGroup.setCreateTime(new Date());
        //所有新增分组默认type就是3，意思是自定义分组
        followingGroup.setType(UserConstant.USER_FOLLOWING_GROUP_TYPE_USER);
        return followingGroupService.addFollowingGroup(followingGroup);
    }

    //获取用户关注分组
    @Override
    public List<FollowingGroup> getUserFollowingGroups(Long userId) {
        return followingGroupService.getUserFollowingGroups(userId);
    }

    @Override
    public List<UserInfo> checkFollowingState(List<UserInfo> userInfoList, Long userId) {
        //先根据用户ID查询出自己关注的所有人
        List<UserFollowing> userFollowings = userFollowingDao.getUserFollowings(userId);
        //遍历userInfoList，看有没有是已经关注了的
        for(UserInfo userInfo: userInfoList){
            userInfo.setFollowed(false);
            for (UserFollowing userFollowing : userFollowings) {
                if(userFollowing.getFollowingId().equals(userInfo.getUserId())){
                    userInfo.setFollowed(true);
                }
            }
        }
        return userInfoList;
    }

}
